package com.didi.gulimall.product.web;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * @author 10626
 */
@Slf4j
@RestController
public class RedissonController {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping("lock")
    public String lock() throws InterruptedException {
        RLock lock = redissonClient.getLock("lock");
        try {
            boolean b = lock.tryLock(2, TimeUnit.SECONDS);
            if (b) {
                Thread.sleep(40000);
                log.info("加锁成功");
                lock.unlock();
            } else {
                return "等待=>" + b;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "加锁成功";
    }

    @GetMapping("write")
    public String write() throws InterruptedException {
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        RLock rLock = readWriteLock.writeLock();
        rLock.tryLock(5, 30, TimeUnit.SECONDS);
        log.info("加写锁成功 {}", Thread.currentThread().getId());
        String uuid = "";
        try {
            uuid = UUID.randomUUID().toString();
            Thread.sleep(30000);
            redisTemplate.opsForValue().set("writevalue", uuid);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            log.info("读锁释放 {}", Thread.currentThread().getId());
            rLock.unlock();
        }
        return "加锁成功";
    }

    @GetMapping("read")
    public String read() {
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        RLock rLock = readWriteLock.readLock();
        rLock.lock();
        String uuid = "";
        try {
            log.info("加读锁成功 {}", Thread.currentThread().getId());
            uuid = redisTemplate.opsForValue().get("writevalue");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            log.info("读锁释放 {}", Thread.currentThread().getId());
            rLock.unlock();
        }
        return uuid;
    }

    @GetMapping("peek")
    public String latch() throws InterruptedException {
        RSemaphore park = redissonClient.getSemaphore("park");
        boolean b = park.tryAcquire(2, TimeUnit.SECONDS);
        if (b) {
            return "ok=>" + b;
        } else {
            return "等待" + b;
        }
    }

    @GetMapping("drive")
    public String drive() {
        RSemaphore park = redissonClient.getSemaphore("park");
        park.release();
        return "ok";
    }

    @GetMapping("go/{id}")
    public String go(@PathVariable("id") String id) {
        RCountDownLatch anyCountDownLatch = redissonClient.getCountDownLatch("anyCountDownLatch");
        anyCountDownLatch.countDown();
        return "ok";
    }

    @GetMapping("door")
    public String downDoor() throws InterruptedException {
        Semaphore semaphore = new Semaphore(4);
        boolean b = semaphore.tryAcquire(2, TimeUnit.SECONDS);
        if (b){
            try {

            } catch (Exception e) {
                semaphore.release();
            }
        }
        RCountDownLatch anyCountDownLatch = redissonClient.getCountDownLatch("anyCountDownLatch");
        anyCountDownLatch.trySetCount(4L);
        anyCountDownLatch.await();
        return "放假了";
    }
}

